package com.qianniu.napi.admin.service.akka;


import akka.actor.UntypedActor;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.base.Strings;
import com.qianniu.napi.admin.entity.*;
import com.qianniu.napi.admin.entity.penum.*;
import com.qianniu.napi.admin.mapper.GoodsFanliMapper;
import com.qianniu.napi.admin.service.*;
import com.qianniu.napi.common.config.Constants;
import com.qianniu.napi.common.util.DateUtil;
import com.qianniu.napi.common.util.RandSplitNumUtils;
import com.qianniu.napi.common.util.SpringUtil;
import com.qianniu.napi.common.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.*;

public class OrderActor extends UntypedActor {

    private final static Logger logger = LoggerFactory.getLogger(OrderActor.class);

    private IActgxService actgxService = (IActgxService) SpringUtil.getBean("actgxServiceImpl");
    private IUserService userService = (IUserService) SpringUtil.getBean("userServiceImpl");
    private ICouponService couponService = (ICouponService) SpringUtil.getBean("couponServiceImpl");
    private IUserstatService userstatService = (IUserstatService) SpringUtil.getBean("userstatServiceImpl");
    private IJifenService jifenService = (IJifenService) SpringUtil.getBean("jifenServiceImpl");
    private IFensService fensService = (IFensService) SpringUtil.getBean("fensServiceImpl");
    private IRedisService redisService = (IRedisService) SpringUtil.getBean("redisServiceImpl");
    private IFenxiaoService fenxiaoService = (IFenxiaoService) SpringUtil.getBean("fenxiaoServiceImpl");
    private IFenxiaoFanService fenxiaoFanService = (IFenxiaoFanService) SpringUtil.getBean("fenxiaoFanServiceImpl");
    private IOrderService orderService = (IOrderService) SpringUtil.getBean("orderServiceImpl");
    private ICzfanService czfanService = (ICzfanService) SpringUtil.getBean("czfanServiceImpl");
    private IJifenFlowService jifenFlowService = (IJifenFlowService) SpringUtil.getBean("jifenFlowServiceImpl");
    private IXnbiService xnbiService = (IXnbiService) SpringUtil.getBean("xnbiServiceImpl");
    private ICouponTplService couponTplService = (ICouponTplService) SpringUtil.getBean("couponTplServiceImpl");
    private IOrderGoodsService orderGoodsService = (IOrderGoodsService) SpringUtil.getBean("orderGoodsServiceImpl");
    private IGoodsService goodsService = (IGoodsService) SpringUtil.getBean("goodsServiceImpl");
    private IXnbiFlowService xnbiFlowService = (IXnbiFlowService) SpringUtil.getBean("xnbiFlowServiceImpl");
    private IAccountFlowService accountFlowService = (IAccountFlowService) SpringUtil.getBean("accountFlowServiceImpl");
    private IAccountService accountService = (IAccountService) SpringUtil.getBean("accountServiceImpl");
    private IMerchantAppService merchantAppService = (IMerchantAppService) SpringUtil.getBean("merchantAppServiceImpl");
    private IMaccountService maccountService = (IMaccountService) SpringUtil.getBean("maccountServiceImpl");
    private IMaccountFlowService maccountFlowService = (IMaccountFlowService) SpringUtil.getBean("maccountFlowServiceImpl");
    private IQnpay qnpay = (IQnpay) SpringUtil.getBean("qnpayImpl");
    private IPintuanOpenService pintuanOpenService = (IPintuanOpenService) SpringUtil.getBean("pintuanOpenServiceImpl");
    private IPintuanLogService pintuanLogService = (IPintuanLogService) SpringUtil.getBean("pintuanLogServiceImpl");
    private IMerchantConfigService merchantConfigServiceImpl = (IMerchantConfigService) SpringUtil.getBean("merchantConfigServiceImpl");
    private ITplformService tplformService = (ITplformService) SpringUtil.getBean("tplformServiceImpl");
    private ITemplatemsgService templatemsgService = (ITemplatemsgService) SpringUtil.getBean("templatemsgServiceImpl");
    private ISmslogService smslogService = (ISmslogService) SpringUtil.getBean("smslogServiceImpl");
    private IMconfigExtService mconfigExtService = (IMconfigExtService) SpringUtil.getBean("mconfigExtServiceImpl");
    private ICutpriceOpenService cutpriceOpenService = (ICutpriceOpenService) SpringUtil.getBean("cutpriceOpenServiceImpl");
    private IStoreService storeService = (IStoreService) SpringUtil.getBean("storeServiceImpl");
    private IShareOpenService shareOpenService = (IShareOpenService) SpringUtil.getBean("shareOpenServiceImpl");
    private IShareService shareService = (IShareService) SpringUtil.getBean("shareServiceImpl");
    private IGoodsQunzfService goodsQunzfService = (IGoodsQunzfService) SpringUtil.getBean("goodsQunzfServiceImpl");
    private GoodsFanliMapper goodsFanliMapper = (GoodsFanliMapper) SpringUtil.getBean("goodsFanliMapper");

    @Override
    public void onReceive(Object message) {
        logger.info(">>>>>>OrderActor in");

        if (message instanceof String) {
            String msg = message.toString();
            logger.info(">>>>>>OrderActor receive message:" + msg);
            try {
                //格式 type+uid+toke
                String[] arr = msg.split("@");
                logger.info(">>>>>>receive arr.length=" + arr.length);
//             if (arr.length < 3) return;

                String type = arr[0];
                String yw1 = arr[1];
                String yw2 = arr.length >= 3 ? arr[2] : "";
                String yw3 = arr.length >= 4 ? arr[3] : "";
                logger.info(">>>>>>receive type:" + type);
                logger.info(">>>>>>receive yw1:" + yw1);
                logger.info(">>>>>>receive yw2:" + yw2);

                switch (type) {
                    case Constants.AKKA_MSG_ORDER_ZIGOUFAN:
                        logger.info(">>>>>>switch here[AKKA_MSG_ORDER_ZIGOUFAN]");
                        zigouFan(yw1, yw2);//oid,gid,uid
                        break;
                    case Constants.AKKA_MSG_ORDER_SHAREFAN:
                        logger.info(">>>>>>switch here[AKKA_MSG_ORDER_ZIGOUFAN]");
                        shareFanPay(yw1);//oid
                        break;
                    case Constants.AKKA_MSG_ORDER_STORE_PAY:
                        logger.info(">>>>>>switch here[AKKA_MSG_ORDER_STORE_PAY]");
                        orderStorePayRuzhang(yw1);//oid,gid,uid
                        break;
                    default:
                        break;
                }
            } catch (Exception e) {
                logger.error(">>>>>>OrderActor process error", e);
            }
        }
    }

    //商家卖货收款
    private void orderStorePay(Order order, boolean ruzhang, BigDecimal minprice) {

        logger.debug("======orderStorePay coming for order =" + JSON.toJSONString(order));
        if (order.getSid() == null || order.getSid().longValue() == 0) {
            logger.debug("======orderStorePay order.getSid() =" + order.getSid());
            return;
        }

        //入账到商家总管理员账户
        User user = userService.selectOne(new EntityWrapper<User>()
                .eq("is_mch", 1).eq("is_admin", 1).eq("sid", order.getSid()));

        if (user == null) {
            logger.debug("==================orderStorePay cannt found muser for sid=" + order.getSid());
            return;
        }

        BigDecimal zero = new BigDecimal(0);

        AccountFlow af = new AccountFlow();
        //营销成本付给商家，对于商家来说是入账，
        //可用金额，所以设置 setAmount 这个字段
        af.setAmount(minprice);
        af.setDikou(zero);//对应营销金额
        af.setRealpay(zero);
        af.setTotal(minprice);

        af.setSn(order.getOrderNo());
        af.setIotype(IotypeEnum.input.getVal());//商家个人账户入账
        af.setXftype(XftypeEnum.sell.getVal());//对笔流水对于商家是卖货

        af.setNickname(user != null ? user.getNickName() : null);
        af.setHeadimg(user != null ? user.getAvatarPic() : null);
        af.setPhone(user != null ? user.getPhone() : null);

        af.setIsConfirm(-1);
        af.setState(1);

        af.setTradetime(order.getCreatetime());
        af.setCreatetime(af.getTradetime());
        af.setRemark(XftypeEnum.sell.getName());
        af.setMid(order.getMid());
        af.setMpid(order.getMpid());
        af.setUid(user.getId());
        af.insert();

        boolean flag = false;
        Account naccount = new Account();
        while (!flag) {

            Account account = accountService.selectOne(new EntityWrapper<Account>().eq("uid", user.getId()));
            if (account == null) {
                account = initAccount(user.getId(), af.getMid(), af.getMpid());
            }
            af.setTransactionid(order.getTransactionId());
            af.setIsConfirm(1);
            af.setLasttotal(account.getTotal());
            af.setConfirmDate(new Date());

            Long version = account.getVersion();

            BigDecimal total = account.getTotal();
            BigDecimal amount = account.getAmount();
            BigDecimal unuseAmount = account.getUnuseAmount();
            BigDecimal fanliing = account.getFanliing();

            //========商家卖货收款======
            naccount.setTotal(total.add(af.getRealpay()).add(af.getAmount()));
            if (ruzhang) {
                naccount.setAmount(amount.add(af.getAmount()));
            } else {
                naccount.setUnuseAmount(unuseAmount.add(af.getAmount()));
                naccount.setFanliing(fanliing.add(af.getAmount()));
            }

            naccount.setModifytime(new Date());
            naccount.setModifier(user.getId());

            naccount.setMid(af.getMid());
            naccount.setMpid(af.getMpid());
            naccount.setVersion(version + 1);

            flag = accountService.update(naccount, new EntityWrapper<Account>()
                    .eq("uid", user.getId()).eq("version", version));

            if (flag) {
                af.insertOrUpdate();
            }
        }
    }

    private void orderStorePayRuzhang(String oid) {

        Order order = orderService.selectById(oid);
        logger.debug("======orderStorePayRuzhang coming for order =" + JSON.toJSONString(order));
        if (order == null || order.getSid() == null || order.getSid().longValue() == 0) {
            logger.debug("======orderStorePayRuzhang order.getSid() =" + order.getSid());
            return;
        }

        User user = userService.selectOne(new EntityWrapper<User>()
                .eq("is_mch", 1).eq("is_admin", 1)
                .eq("sid", order.getSid()));
        logger.debug("---------------------------orderStorePayRuzhang  user =" + JSON.toJSONString(user));
        if (user == null) {
            logger.debug("======orderStorePayRuzhang user cannt found muser for sid=" + order.getSid());
            return;
        }

        AccountFlow af = accountFlowService.selectOne(new EntityWrapper<AccountFlow>()
                .eq("sn", order.getOrderNo())
                .eq("xftype", XftypeEnum.sell.getVal())
        );
        logger.debug("---------------------------orderStorePayRuzhang  af =" + JSON.toJSONString(af));

        if (af == null) {
            logger.debug("---------------------------orderStorePayRuzhang af cannt found muser for sid=" + order.getSid());
            return;
        }

        boolean flag = false;
        Account naccount = new Account();
        while (!flag) {

            Long touid = af.getUid();
            Account account = accountService.selectOne(new EntityWrapper<Account>().eq("uid", user.getId()));

            Long version = account.getVersion();
            BigDecimal amount = account.getAmount();
            BigDecimal unuseAmount = account.getUnuseAmount();
            BigDecimal fanli = account.getFanli();//累计佣金
            BigDecimal fanliing = account.getFanliing();

            naccount.setAmount(amount.add(af.getAmount()));
            naccount.setUnuseAmount(unuseAmount.subtract(af.getAmount()));

            naccount.setFanli(fanli.add(af.getAmount()));
            naccount.setFanliing(fanliing.subtract(af.getAmount()));

            naccount.setModifytime(new Date());
            naccount.setModifier(touid);
            naccount.setVersion(version + 1);

            flag = accountService.update(naccount, new EntityWrapper<Account>().eq("uid", touid).eq("version", version));
        }
    }

    public Account initAccount(Long uid, Long mid, Long mpid) {

        BigDecimal zero = new BigDecimal(0);

        Account act = new Account();
        act.setUid(uid);
        act.setMid(mid);
        act.setMpid(mpid);
        act.setCreatetime(new Date());
        act.setVersion(1l);


        User user = userService.selectById(uid);
        act.setNickname(user != null ? user.getNickName() : null);
        act.setHeadimg(user != null ? user.getAvatarPic() : null);
        act.setPhone(user != null ? user.getPhone() : null);

        act.setTotal(zero);
        act.setAmount(zero);
        act.setUnuseAmount(zero);
        act.setFanli(zero);
        act.setFanliing(zero);
        act.setFreeze(zero);
        act.setChargeAmount(zero);
        act.setLjxiaofei(zero);
        act.setMamount(zero);
        act.setWithdraw(zero);
        act.insert();
        return act;
    }

    public Maccount initMaccount(Long uid, Long mid) {

        BigDecimal zero = new BigDecimal(0);

        Maccount act = new Maccount();
        act.setUid(uid);
        act.setMid(mid);
        act.setCreatetime(new Date());
        act.setVersion(1l);
        act.setState(1);

        act.setTotal(zero);
        act.setAmount(zero);
        act.setSaleAmount(zero);
        act.setMamount(zero);
        act.setUnuseAmount(zero);
        act.setFanliing(zero);
        act.setFreeze(zero);
        act.setChargeAmount(zero);
        act.setWithdraw(zero);
        act.setConsume(zero);
        //sms
        act.setSmsmout(new BigDecimal("80"));
        act.setSmsmoutTotal(new BigDecimal("80"));
        act.setSmsprice(new BigDecimal("0.08"));
        act.setSmstotal(1000);
        act.insert();

        logger.info("========initMaccount=" + JSON.toJSONString(act));
        return act;
    }

    public Xnbi initXnbi(Long uid, Long mid, Long mpid) {

        BigDecimal zero = new BigDecimal(0);

        Xnbi act = new Xnbi();
        act.setUid(uid);
        act.setMid(mid);
        act.setMpid(mpid);

        act.setCreatetime(new Date());
        act.setVersion(1l);
        act.setTotal(zero);
        act.setFanliing(zero);
        act.setState(1);
        act.insert();
        return act;
    }

    public Jifen initJifen(Long uid, Long mid, Long mpid) {

        BigDecimal zero = new BigDecimal(0);
        Jifen act = new Jifen();
        act.setUid(uid);
        act.setMid(mid);
        act.setMpid(mpid);

        act.setCreatetime(new Date());
        act.setVersion(1l);
        act.setTotal(zero);
        act.setFanliing(zero);
        act.setState(1);
        act.insert();
        return act;
    }


    private Order jshuifei(int level, Order order, FenxiaoFan fxfan, BigDecimal jiandian) {
        //计算分销额
        if (level == 1) {
            order.setFxe1(order.getRealpay().multiply(fxfan.getFan1()).divide(new BigDecimal(100)));
            if (fxfan.getIsJiandian() == 1) order.setFxe1(order.getFxe1().add(jiandian));
        } else if (level == 2) {
            order.setFxe2(fxfan.getFan2());

            if (fxfan.getIsJiandian() == 1) order.setFxe2(order.getFxe2().add(jiandian));

        } else if (level == 3) {
            order.setFxe3(fxfan.getFan3());

            if (fxfan.getIsJiandian() == 1) order.setFxe3(order.getFxe3().add(jiandian));

        } else if (level == 4) {
            order.setFxe4(fxfan.getFan4());

            if (fxfan.getIsJiandian() == 1) order.setFxe4(order.getFxe4().add(jiandian));

        } else if (level == 5) {
            order.setFxe5(fxfan.getFan5());

            if (fxfan.getIsJiandian() == 1) order.setFxe5(order.getFxe5().add(jiandian));

        } else if (level == 6) {
            order.setFxe6(fxfan.getFan6());

            if (fxfan.getIsJiandian() == 1) order.setFxe6(order.getFxe6().add(jiandian));

        } else if (level == 7) {
            order.setFxe7(fxfan.getFan7());

            if (fxfan.getIsJiandian() == 1) order.setFxe7(order.getFxe7().add(jiandian));
        }
        return order;
    }

    //处理商品直接推荐返利
    //先进入待入账佣金，再发放（后发放）
    //奖励的其他类型佣金不在进行第二次方法
    public void shareFanPay(String oid) {

        logger.info("----------------------------------------------------------------------------shareFanPay come");
        if (Strings.isNullOrEmpty(oid)) {
            return;
        }
        Order order = orderService.selectById(oid);
        Long uid = order.getUid();
        Long mid = order.getMid();
        Long mpid = order.getMpid();
        String sn = order.getOrderNo();

        AccountFlow af = accountFlowService.selectOne(new EntityWrapper<AccountFlow>()
                .eq("sn", sn)
                .eq("xftype", XftypeEnum.sharefan.getVal())
        );
        logger.info("----------------------------------------------------------------------------shareFanPay af=" + af);

        Boolean flag = false;
        if (af != null) {
            uid = af.getUid();
            MerchantConfig mconfig = redisService.getMconfig(order.getMpid());
            User user = userService.selectById(uid);
            MerchantApp mapp = redisService.getMApp(mpid);
            boolean fanxian = mconfig.getIsAutofan() == 1 && mconfig.getIsMiaotui() == 1;
            logger.info("----------------------------------------------------------------------------shareFanPay fanxian=" + fanxian);

            if (fanxian) {
                Map<String, Object> paymap = qnpay.payPakect(user.getMpid(), mapp.getAppid(), user, af.getAmount(), "用户分享佣金奖励", "127.0.0.1");
                //如果秒退失败，该佣金自动到用户账户
                logger.info("----------------------------------------------------------------------------shareFanPay paymap=" + JSON.toJSONString(paymap));
                if (paymap.containsKey("result_code") && paymap.get("result_code").toString().equals("FAIL")) {
                    flag = false;
                } else if (paymap.containsKey("result_code") && paymap.get("result_code").toString().equals("SUCCESS")) {
                    //平台账户记账
                    addMaccountFlow(user, af.getAmount(), sn, IotypeEnum.output, XftypeEnum.withdraw);

                    //用户账户记账
                    af.setId(null);
                    af.setIotype(IotypeEnum.output.getVal());//个人账户出账
                    af.setXftype(XftypeEnum.withdraw.getVal());//个人消费
                    af.setIsConfirm(1);
                    af.setConfirmDate(new Date());

                    af.setState(1);
                    af.setCreatetime(new Date());
                    af.setRemark("佣金提现至微信账户");
                    af.insert();

                    Account naccount = new Account();
                    while (!flag) {
                        Account account = accountService.selectOne(new EntityWrapper<Account>().eq("uid", uid));
                        if (account == null) {
                            account = initAccount(uid, mid, mpid);
                        }

                        Long version = account.getVersion();

                        BigDecimal total = account.getTotal();
                        BigDecimal fanliing = account.getFanliing();
                        BigDecimal unuseAmount = account.getUnuseAmount();

                        naccount.setTotal(total.subtract(af.getAmount()));
                        naccount.setUnuseAmount(unuseAmount.subtract(af.getAmount()));
                        naccount.setFanliing(fanliing.subtract(af.getAmount()));

                        naccount.setModifytime(new Date());
                        naccount.setModifier(uid);
                        naccount.setVersion(version + 1);

                        flag = accountService.update(naccount, new EntityWrapper<Account>().eq("uid", uid).eq("version", version));
                    }
                }
            }

            //如果秒退失败，该佣金自动到用户账户
            Account naccount = new Account();
            while (!flag) {
                Account account = accountService.selectOne(new EntityWrapper<Account>().eq("uid", uid));
                if (account == null) {
                    break;
                }
                Long version = account.getVersion();

                BigDecimal amount = account.getAmount();
                BigDecimal fanliing = account.getFanliing();
                BigDecimal unuseAmount = account.getUnuseAmount();
                BigDecimal fanli = account.getFanli();

                naccount.setAmount(amount.add(af.getAmount()));
                naccount.setUnuseAmount(unuseAmount.subtract(af.getAmount()));
                naccount.setFanliing(fanliing.subtract(af.getAmount()));
                naccount.setFanli(fanli.add(af.getAmount()));

                naccount.setModifytime(new Date());
                naccount.setModifier(uid);
                naccount.setVersion(version + 1);

                flag = accountService.update(naccount, new EntityWrapper<Account>().eq("uid", uid).eq("version", version));
            }
        }
    }

    //群转发
    //奖励的其他类型佣金不在进行第二次方法
    //群发奖励不支持退款
    public void qunzhuanfaPay(String shareid) {

        logger.info("----------------------------------------------------------------------------qunzhuanfaPay come");
        Share share = shareService.selectById(shareid);
        logger.debug("----------------------------------------------------------------------------share=" + share);
        if (share == null) return;

        //返现用户
        Long mpid = share.getMpid();
        Long uid = share.getUid();
        Long ywid = share.getYwid();

        logger.debug("-----------------qunzhuanfaPay mpid=" + mpid);
        logger.debug("-----------------qunzhuanfaPay uid=" + uid);
        logger.debug("-----------------qunzhuanfaPay ywid=" + ywid);
        if (ywid == null) return;

        GoodsQunzf goodsQunzf = goodsQunzfService.selectById(ywid);
        logger.debug("-----------------qunzhuanfaPay goodsQunzf=" + goodsQunzf);
        if (goodsQunzf == null) return;

        User user = userService.selectById(uid);
        if (user == null) return;

        //规则1：一个商品对一个人一个群只有一次奖励【系统默认】
        //规则2：一个人一个活动一天只限制群发奖励一次
        //规则3：同一个活动同一个人限制群发奖励次数
        //规则4： 群发奖励超过份数，则不再发群发红包
        Integer todaycout = shareService.selectCount(new EntityWrapper<Share>()
                .eq("sendoff", 1)
                .eq("uid", share.getUid())
                .eq("ywid", share.getYwid())
                .eq("sentdate", DateUtil.getToday()));
        logger.debug("---------------------------------------qunzhuanfaPay and todaycout=" + todaycout);
        if (todaycout > 0) return;

        //【同一个活动同一个人限制群发奖励次数】
        Integer hdcout = shareService.selectCount(new EntityWrapper<Share>()
                .eq("ywid", share.getYwid())
                .eq("sendoff", 1)
                .eq("uid", share.getUid()));
        logger.debug("---------------------------------------qunzhuanfaPay and hdcout=" + hdcout);
        if (hdcout >= goodsQunzf.getOneptimes()) return;

        Integer sendoffcout = shareService.selectCount(new EntityWrapper<Share>()
                .eq("ywid", share.getYwid())
                .eq("sendoff", 1));
        logger.debug("-----------------qunzhuanfaPay sendoffcout=" + sendoffcout);
        logger.debug("-----------------goodsQunzf.jiang_fenshu=" + goodsQunzf.getJiangFenshu());

        //群发奖励超过份数，则不再发群发红包
        if (goodsQunzf.getJiangFenshu() != null && goodsQunzf.getJiangFenshu() > 0
                && sendoffcout >= goodsQunzf.getJiangFenshu()) {
            return;
        }

        //计算佣金随机
        BigDecimal money = RandSplitNumUtils.genRandPack(goodsQunzf.getJiangMount().intValue());
        if (money.doubleValue() > goodsQunzf.getJiangMount().doubleValue()) money = goodsQunzf.getJiangMount();
        if (goodsQunzf.getJiangType().intValue() != XffanType.qian.getVal()) {
            money = new BigDecimal(money.intValue());
        }

        //群发奖励直接奖励，自动奖励
        //否则先放入待返利中。。。
        String sn = StringUtil.getSnNo("QTYJ");
        if (goodsQunzf.getJiangType() == XffanType.jifen.getVal())
            fanyong(user, money, XffanType.jifen.getVal(), sn, true, true, XftypeEnum.autofanli);
        if (goodsQunzf.getJiangType() == XffanType.qian.getVal())
            fanyong(user, money, XffanType.qian.getVal(), sn, true, true, XftypeEnum.autofanli);
        if (goodsQunzf.getJiangType() == XffanType.xnbi.getVal())
            fanyong(user, money, XffanType.xnbi.getVal(), sn, true, true, XftypeEnum.autofanli);

        share.setModifytime(new Date());
        share.setModifier(uid);
        share.setSendoff(1);
        share.setSentdate(DateUtil.getToday());
        share.updateById();

        logger.info("--------------------------------------------------------------qunzhuanfaPay over");
    }

    //核销之后自购返处理逻辑
    public void zigouFan(String id, String fantimeType) {
        logger.info("----------------------------------------------------------------------------zigouFan with fantimeType come");
        Order order = orderService.selectById(id);
        if (order == null) {
            logger.info("------------------------zigouFan with fantimeType order is null for oid=" + id);
            return;
        }

        Long uid = order.getUid();
        User user = userService.selectById(uid);
        if (user == null) {
            logger.info("------------------------zigouFan with fantimeType user is null for uid=" + uid);
            return;
        }
        Goods goods = goodsService.selectById(order.getGid());
        MerchantConfig mconfig = redisService.getMconfig(order.getMpid());
        if (mconfig.getFantimeType().intValue() == FantimeType.payok.getVal()) return;//zigouFan(Order order) method已处理
        GoodsFanli fanli = goodsFanliMapper.selectById(order.getGid());
        //处理自购奖励返券
        if (fanli != null && fanli.getFantimeType() == FantimeType.payok.getVal()) {
            //处理自购返券
            if (fanli.getZgfanType() != null &&
                    fanli.getZgfanType().intValue() == XffanType.quan.getVal()) zigouFanquan(order);
        }

        zigouFan(order,fanli);
    }

    public void zigouFan(Order order,GoodsFanli fanli) {

        logger.info("----------------------------------------------------------------------------zigouFan come");
        //返现用户
        Long mpid = order.getMpid();
        Long uid = order.getUid();
        logger.info("-----------------zigouFan mpid=" + mpid);

        User user = userService.selectById(uid);
        if (user == null) {
            logger.info("------------------------zigouFan user is null for uid=" + uid);
            return;
        }

        //秒到+非秒到账
        BigDecimal bi = order.getFanbi();
        BigDecimal jifen = order.getFanjifen();
        BigDecimal qian = order.getFanqian();

        logger.info("--------------------------------------zigouFan start jifen=" + jifen);
        logger.info("--------------------------------------zigouFan start qian=" + qian);
        logger.info("--------------------------------------zigouFan start bi=" + bi);

        MerchantConfig mconfig = redisService.getMconfig(mpid);

        //mconfig.getIsMiaotui() 该属性针对现金返佣来说
        //mconfig.getIsAutofan() 该属性针对现金返佣来说
        //直接入账触发点 1：支付成功后；2：确认收货|扫码核销后；3：确认后7天到账&
        //否则先放入待返利中。。。
        boolean ruzhang = fanli.getFantimeType().intValue() == FantimeType.payok.getVal();
        if(!ruzhang)return;
        boolean autofan = mconfig.getIsAutofan() == 1;

        if (jifen != null && jifen.doubleValue() > 0)
            fanyong(user, jifen, XffanType.jifen.getVal(), order.getOrderNo(), ruzhang, autofan, XftypeEnum.xffanli);
        if (qian != null && qian.doubleValue() > 0)
            fanyong(user, qian, XffanType.qian.getVal(), order.getOrderNo(), ruzhang,
                    autofan && mconfig.getIsMiaotui() == 1, XftypeEnum.xffanli);
        if (bi != null && bi.doubleValue() > 0)
            fanyong(user, bi, XffanType.xnbi.getVal(), order.getOrderNo(), ruzhang, autofan, XftypeEnum.xffanli);

        logger.info("------------------------------------------------zigouFan over");
    }

    public void zigouFanquan(Order order) {

        logger.info("----------------------------------------------------------------------------zigouFanquan come");

        //返现用户
        Long mpid = order.getMpid();
        Long uid = order.getUid();
        logger.info("======zigouFan mpid=" + mpid);

        List<OrderGoods> oglist = orderGoodsService.selectList(new EntityWrapper<OrderGoods>()
                .setSqlSelect("oid,gid")
                .eq("oid", order.getId()));
        List<String> gidlist = new ArrayList<String>();
        for (OrderGoods item : oglist) {
            if (item.getGid() != null) gidlist.add(item.getGid().toString());
        }

        if (gidlist.size() == 0) {
            logger.info("-----------------------------------------------gidlist.size()==0");
            return;
        }
        List<Goods> goodslist = goodsService.selectBatchIds(gidlist);
        for (Goods item : goodslist) {
            logger.info("----------------------------------------------------------------------------zigouFanquan Goods item=" + JSON.toJSONString(item));
            GoodsFanli fanli = goodsFanliMapper.selectById(item.getId());
            if (fanli.getZgfanType() == 3 && fanli.getZgfanYwid() != null) {
                int num = fanli.getZgfanMount();
                Long tplid = fanli.getZgfanYwid();
                CouponTpl ctpl = couponTplService.selectById(tplid);
                for (int i = 0; i < num; i++) {
                    Coupon coupon = new Coupon();
                    coupon.setIsUnused(1);
                    coupon.setIsUsed(0);
                    coupon.setIsForever(0);
                    coupon.setIsOutdate(0);
                    coupon.setState(1);

                    coupon.setMid(order.getMid());
                    coupon.setMpid(order.getMpid());
                    coupon.setUid(order.getUid());
                    coupon.setCreatetime(new Date());

                    coupon.setTplid(ctpl.getId());
                    coupon.setType(ctpl.getType());
                    coupon.setName(ctpl.getName());

                    coupon.setCno(StringUtil.getQuanCode(order.getMid()));

                    coupon.setStarttime(ctpl.getValidType() == 1 ? DateUtil.getToday() : ctpl.getStarttime());
                    coupon.setEndtime(ctpl.getIsForever() == 1 ? null : ctpl.getValidType() == 1 ? DateUtil.addToday(ctpl.getExpire()) : ctpl.getEndtime());
                    coupon.setCost(ctpl.getCost());
                    coupon.setUsemin(ctpl.getUsemin());
                    coupon.setOriginType(4);//领券来源@1：领取；2：分享；3：赠送;4：充值&

                    coupon.insert();
                }

                CouponTpl ctpl2 = new CouponTpl();
                ctpl2.setUse(ctpl.getUse() + num);
                ctpl2.setId(ctpl.getId());
                ctpl2.updateById();
            }
        }

        logger.info("======zigouFanquan over");
    }

    public void shengjiCheck(String uid, String type, String ywid) {
        logger.info("-----------------------------------start to shengjiCheck uid=" + uid);
        logger.info("-----------------------------------start to shengjiCheck type=" + type);
        logger.info("-----------------------------------start to shengjiCheck ywid=" + ywid);

        Account account = accountService.selectOne(new EntityWrapper<Account>()
                .setSqlSelect("uid,ljxiaofei,charge_amount chargeAmount")
                .eq("uid", uid));
        User user = userService.selectById(uid);
        Long mpid = user.getMpid();

        logger.debug("===shengjiCheck user=" + user);
        int mlevel = user.getMemberLevel();
        int oldlevel = mlevel;
        BigDecimal zhekou = new BigDecimal(1);
        Fenxiao fenxiao = fenxiaoService.selectOne(new EntityWrapper<Fenxiao>().eq("mpid", mpid));
        if (fenxiao == null) {
            logger.info("=====fenxiao not exist for mpid=" + mpid);
            return;
        }

        if (fenxiao.getHuiyuantype() == Huiyuantype.charge.getVal() && !Strings.isNullOrEmpty(ywid)
                && !Strings.isNullOrEmpty(type) && type.equals("recharge")) {
            Czfan czfan = czfanService.selectById(ywid);
            if (czfan == null) {
                return;
            }
            mlevel = czfan.getLevel();
        } else if (fenxiao.getHuiyuantype() == Huiyuantype.hygoods.getVal() && !Strings.isNullOrEmpty(ywid)
                && !Strings.isNullOrEmpty(type) && type.equals("hygoods")) {

            Goods hygoods = goodsService.selectById(ywid);
            mlevel = hygoods != null && hygoods.getMlevel() != null ? hygoods.getMlevel() : 0;
            logger.info("-----------------------------------------------start to check huiyuan mlevel=" + mlevel);

            if (mlevel < 0 || fenxiao == null || mlevel > fenxiao.getFxlevel()) {
                logger.error("-----------------------------------------------fenxiao.getHuiyuantype()==Huiyuantype.hygoods.getVal() mlevel=" + mlevel);
                return;
            }
        } else if (fenxiao.getHuiyuantype() == Huiyuantype.xiaofei.getVal()) {

            if (account.getLjxiaofei() == null) {
                logger.error("-----------------------------------------------fenxiao.getHuiyuantype()==Huiyuantype.hygoods.getVal() mlevel=" + mlevel);
                return;
            }

            if (account.getLjxiaofei().doubleValue() >= fenxiao.getHuifei7().doubleValue()) {
                mlevel = 7;
            } else if (account.getLjxiaofei().doubleValue() >= fenxiao.getHuifei6().doubleValue()) {
                mlevel = 6;
            } else if (account.getLjxiaofei().doubleValue() >= fenxiao.getHuifei5().doubleValue()) {
                mlevel = 5;
            } else if (account.getLjxiaofei().doubleValue() >= fenxiao.getHuifei4().doubleValue()) {
                mlevel = 4;
            } else if (account.getLjxiaofei().doubleValue() >= fenxiao.getHuifei3().doubleValue()) {
                mlevel = 3;
            } else if (account.getLjxiaofei().doubleValue() >= fenxiao.getHuifei2().doubleValue()) {
                mlevel = 2;
            } else if (account.getLjxiaofei().doubleValue() >= fenxiao.getHuifei1().doubleValue()) {
                mlevel = 1;
            }

        } else if (fenxiao.getHuiyuantype() == Huiyuantype.xianxia.getVal()) {
            //===待完善，表单提交控制,同步更新会员级别
        }

        //更新粉丝状态
        MerchantConfig mconfig = redisService.getMconfig(mpid);
        if (mconfig.getIsSuofen() == 1) {
            //Fens fens=  fensService.selectOne(new EntityWrapper<Fens>().setSqlSelect("id,status").eq("uid",uid));
            Fens fens = new Fens();
            fens.setStatus(2);
            fensService.update(fens, new EntityWrapper<Fens>().setSqlSelect("id,status").eq("uid", uid));
        } else {
            //====待完善，非锁粉模式下
        }

        if (mlevel <= oldlevel) {
            logger.info("------------------------------------mlevel<=oldlevel return and mlevel=" + mlevel + " oldlevel=" + oldlevel);
            return;
        }

        zhekou = mlevel == 1 ? fenxiao.getMzhekou1() :
                mlevel == 2 ? fenxiao.getMzhekou2() :
                        mlevel == 3 ? fenxiao.getMzhekou3() :
                                mlevel == 4 ? fenxiao.getMzhekou4() :
                                        mlevel == 5 ? fenxiao.getMzhekou5() :
                                                mlevel == 6 ? fenxiao.getMzhekou6() :
                                                        mlevel == 7 ? fenxiao.getMzhekou7() : new BigDecimal(100);

        //自动升级会员级别
        //===待处理
        User nuser = new User();
        nuser.setId(user.getId());
        nuser.setMemberLevel(mlevel);//自动升级会员级别
        nuser.setDiscount(zhekou.divide(new BigDecimal(100)));//会员折扣
        nuser.setIsMember(1);        //自动升级会员级别
        nuser.updateById();

        //清楚缓存
        redisService.delUser(user.getId());

    }

    //大礼包拆分到自己名下
    //优惠券大礼包，优惠券放在自己名下
    private void orderDalibao(String oid, String gid, String uid) {

        Goods goods = goodsService.selectById(gid);
        if (Strings.isNullOrEmpty(goods.getQuans())) {
            logger.info("===================orderDalibao goods.getQuans() is null");
            return;
        }

        List<String> ids = Arrays.asList(goods.getQuans().split(";"));
        List<CouponTpl> couponTpls = couponTplService.selectBatchIds(ids);

        for (CouponTpl ctpl : couponTpls) {
            Coupon coupon = new Coupon();
            coupon.setIsUnused(1);
            coupon.setIsUsed(0);
            coupon.setIsForever(0);
            coupon.setIsOutdate(0);
            coupon.setState(1);

            coupon.setMid(goods.getMid());
            coupon.setMpid(goods.getMpid());
            coupon.setUid(goods.getId());

            coupon.setSid(ctpl.getSid());
            coupon.setOid(Long.valueOf(oid));
            coupon.setCreatetime(new Date());

            coupon.setTplid(ctpl.getId());
            coupon.setType(ctpl.getType());
            coupon.setName(ctpl.getName());

            coupon.setCno(StringUtil.getQuanCode(goods.getMpid()));

            coupon.setStarttime(ctpl.getValidType() == 1 ? DateUtil.getToday() : ctpl.getStarttime());
            coupon.setEndtime(ctpl.getIsForever() == 1 ? null : ctpl.getValidType() == 1 ? DateUtil.addToday(ctpl.getExpire()) : ctpl.getEndtime());
            coupon.setCost(ctpl.getCost());
            coupon.setUsemin(ctpl.getUsemin());
            coupon.setOriginType(5);//领券来源@1：领取；2：分享；3：赠送;4：充值;5:购买&
            coupon.insert();
        }
    }

    //返佣金入账（都是首次）
    private void fanyong(User user, BigDecimal fxe, Integer fantype, String sn, Boolean ruzhang, Boolean autofan, XftypeEnum xftypeEnum) {

        Map<String, Object> paymap = new HashMap<String, Object>();
        MerchantApp mapp = redisService.getMApp(user.getMpid());
        MerchantConfig mconfig = redisService.getMconfig(user.getMpid());
        Integer fantime = mconfig.getFantimeType();
        if (fantype == XffanType.jifen.getVal()) {
            //积分入账，除了现金返利都及时入账
            addJifenFlow(user, fxe, ruzhang, fantime, sn, IotypeEnum.input, JftypeEnum.share, "用户分享返积分结算");
        } else if (fantype == XffanType.qian.getVal()) {
            //现金很特殊，区分不同时刻返佣金
            //商家出账记录，对于商家发生实际现金变动时，才会生成记录
            //先入账
            addAccountFlow(user, fxe, ruzhang, fantime, sn, IotypeEnum.input, xftypeEnum);
            if (autofan) {
                paymap = qnpay.payPakect(user.getMpid(), mapp.getAppid(), user, fxe, "用户分享佣金奖励", "127.0.0.1");
                if (paymap.containsKey("result_code") && paymap.get("result_code").toString().equals("SUCCESS")) {
                    //秒到账成功
                    addMaccountFlow(user, fxe, sn, IotypeEnum.output, xftypeEnum);
                    //奖励佣金直接发放
                    addAccountAutoFanFlow(user, fxe, fantime, sn, IotypeEnum.output, xftypeEnum.autofanli);
                }
            }
        } else if (fantype == XffanType.quan.getVal()) {//返券
            //待完善
        } else if (fantype == XffanType.xnbi.getVal()) {//返币
            addXnbiFlow(user, fxe, ruzhang, fantime, sn, IotypeEnum.input, xftypeEnum, "返利分享佣金");
        }
    }

    private void addMaccountFlow(User user, BigDecimal money,
                                 String sn, IotypeEnum iotype, XftypeEnum xftype) {
        Long uid = user.getId();
        Long mid = user.getMid();
        Long mpid = user.getMpid();

        //付款失败，进入待转账流水
        MaccountFlow maf = new MaccountFlow();
        maf.setAmount(money);//实付100剩余20在一次充值时已更新
        maf.setMamount(new BigDecimal(0));//各种抵扣额度=商家的营销费用=总营销金额130

        maf.setUid(uid);
        maf.setMid(mid);
        maf.setMpid(mpid);

        maf.setCreatetime(new Date());
        maf.setTradetime(new Date());
        maf.setIsConfirm(1);
        maf.setConfirmDate(new Date());

        maf.setIotype(iotype.getVal());
        maf.setXftype(xftype.getVal());

        maf.setRemark(xftype.getName());
        maf.setSn(sn);
        maf.insert();

        boolean flag = false;
        //企业付款成功
        Maccount maccount = new Maccount();
        while (!flag) {
            Maccount ma = maccountService.selectOne(new EntityWrapper<Maccount>().eq("mid", mid));
            if (ma == null) {
                ma = initMaccount(uid, mid);
            }

            Long version = ma.getVersion();
            BigDecimal amount = ma.getAmount();
            BigDecimal total = ma.getTotal();
            BigDecimal sale = ma.getSaleAmount();
            BigDecimal market = ma.getMamount();

            maccount.setTotal(iotype.getVal() == -1 ? total.subtract(maf.getAmount()) : total.add(maf.getAmount()));       //总金额
            maccount.setSaleAmount(iotype.getVal() == -1 ? sale.subtract(maf.getAmount()) : sale.add(maf.getAmount()));    //累计销售额度
            maccount.setAmount(iotype.getVal() == -1 ? amount.subtract(maf.getAmount()) : amount.add(maf.getAmount()));    //可用余额
            maccount.setMamount(iotype.getVal() == -1 ? market.subtract(maf.getMamount()) : market.add(maf.getMamount()));  //营销总金额

            maccount.setModifytime(new Date());
            maccount.setModifier(uid);
            maccount.setVersion(version + 1);

            flag = maccountService.update(maccount, new EntityWrapper<Maccount>().eq("id", ma.getId()).eq("version", version));
            logger.info("===========maccount flag=" + flag);
        }
    }

    //返佣流水,iotype==1
    private void addAccountFlow(User user, BigDecimal money, Boolean ruzhang, Integer fantimeType,
                                String sn, IotypeEnum iotype, XftypeEnum xftype) {
        Long uid = user.getId();
        Long mid = user.getMid();
        Long mpid = user.getMpid();

        //付款失败，进入待转账流水
        AccountFlow af = new AccountFlow();
        af.setAmount(money);
        af.setDikou(new BigDecimal(0));//总营销金额 130
        af.setRealpay(new BigDecimal(0));//总价200 实付100
        af.setTotal(af.getAmount());

        User ruser = userService.selectById(uid);
        af.setNickname(ruser != null ? ruser.getNickName() : null);
        af.setHeadimg(ruser != null ? ruser.getAvatarPic() : null);
        af.setPhone(ruser != null ? ruser.getPhone() : null);

        af.setSn(sn);
        af.setIotype(iotype.getVal());//个人账户出账
        af.setXftype(xftype.getVal());//消费类型
        af.setFantimeType(fantimeType);//个人消费

        af.setIsConfirm(1);
        af.setState(1);
        af.setTradetime(new Date());
        af.setCreatetime(new Date());
        af.setRemark(xftype.getName());
        af.setUid(uid);
        af.setMid(mid);
        af.setMpid(mpid);
        af.insert();

        Boolean flag = false;
        Account naccount = new Account();
        while (!flag) {
            Account account = accountService.selectOne(new EntityWrapper<Account>().eq("uid", uid));
            if (account == null) {
                account = initAccount(uid, mid, mpid);
            }
            af.setIsConfirm(1);
            af.setConfirmDate(new Date());

            Long version = account.getVersion();

            BigDecimal total = account.getTotal();
            BigDecimal amount = account.getAmount();

            BigDecimal unuseAmount = account.getUnuseAmount();
            BigDecimal fanliing = account.getFanliing();

            naccount.setTotal(iotype.getVal() == 1 ? total.add(af.getAmount()) : total.subtract(af.getAmount()));

            if (ruzhang)
                naccount.setAmount(iotype.getVal() == 1 ? amount.add(af.getAmount()) : amount.subtract(af.getAmount()));
            else {
                naccount.setFanliing(iotype.getVal() == 1 ? fanliing.add(af.getAmount()) : fanliing.subtract(af.getAmount()));
                naccount.setUnuseAmount(iotype.getVal() == 1 ? unuseAmount.add(af.getAmount()) : unuseAmount);
            }
            naccount.setModifytime(new Date());
            naccount.setModifier(uid);
            naccount.setVersion(version + 1);

            flag = accountService.update(naccount, new EntityWrapper<Account>().eq("uid", uid).eq("version", version));
        }
    }

    //自动发放佣金，不走总账户
    //总账户不增加，可用账户不增加，累计佣金增加
    private void addAccountAutoFanFlow(User user, BigDecimal money, Integer fantimeType,
                                       String sn, IotypeEnum iotype, XftypeEnum xftype) {
        Long uid = user.getId();
        Long mid = user.getMid();
        Long mpid = user.getMpid();

        //付款失败，进入待转账流水
        AccountFlow af = new AccountFlow();
        af.setAmount(new BigDecimal(0));
        af.setDikou(new BigDecimal(0));
        af.setRealpay(money);//实际提现
        af.setTotal(money);

        User ruser = userService.selectById(uid);
        af.setNickname(ruser != null ? ruser.getNickName() : null);
        af.setHeadimg(ruser != null ? ruser.getAvatarPic() : null);
        af.setPhone(ruser != null ? ruser.getPhone() : null);

        af.setSn(sn);
        af.setIotype(iotype.getVal());//个人账户出账
        af.setXftype(xftype.getVal());//消费类型
        af.setFantimeType(fantimeType);//个人消费

        af.setIsConfirm(1);
        af.setConfirmDate(new Date());
        af.setState(1);
        af.setTradetime(new Date());
        af.setCreatetime(af.getTradetime());
        af.setRemark(xftype.getName());

        af.setUid(uid);
        af.setMid(mid);
        af.setMpid(mpid);
        af.insert();

        Boolean flag = false;
        Account naccount = new Account();
        while (!flag) {
            Account account = accountService.selectOne(new EntityWrapper<Account>().eq("uid", uid));
            if (account == null) {
                account = initAccount(uid, mid, mpid);
            }

            Long version = account.getVersion();
            BigDecimal fanli = account.getFanli();

            naccount.setFanli(fanli.add(af.getRealpay()));

            naccount.setModifytime(new Date());
            naccount.setModifier(uid);
            naccount.setVersion(version + 1);

            flag = accountService.update(naccount, new EntityWrapper<Account>().eq("uid", uid).eq("version", version));
        }
    }

    private void addXnbiFlow(User user, BigDecimal money, Boolean ruzhang, Integer fantimeType,
                             String sn, IotypeEnum iotype, XftypeEnum xftype, String remark) {
        Long uid = user.getId();
        Long mid = user.getMid();
        Long mpid = user.getMpid();

        XnbiFlow xflow = new XnbiFlow();
        xflow.setConfirmDate(new Date());
        xflow.setCreatetime(new Date());
        xflow.setIotype(iotype.getVal());
        xflow.setIsConfirm(1);
        xflow.setJftype(xftype.getVal());
        xflow.setFantimeType(fantimeType);//===待实现

        xflow.setUid(uid);
        xflow.setMid(mid);
        xflow.setMpid(mpid);
        xflow.setRemark(remark);
        xflow.setNum(money);
        xflow.setSn(sn);
        xflow.setState(1);
        logger.debug("======xflow=" + xflow);
        xflow.insert();

        ruzhang = true;//及时入账

        Boolean flag = false;
        while (!flag) {
            Xnbi xbi = xnbiService.selectOne(new EntityWrapper<Xnbi>().eq("uid", uid));
            if (xbi == null) xbi = initXnbi(uid, mid, mpid);
            Long version = xbi.getVersion();
            BigDecimal total = xbi.getTotal();
            BigDecimal fanliing = xbi.getFanliing();

            if (ruzhang) xbi.setTotal(iotype.getVal() == 1 ? total.add(money) : total.subtract(money));
            else xbi.setFanliing(iotype.getVal() == 1 ? fanliing.add(money) : fanliing.subtract(money));

            xbi.setModifytime(new Date());
            xbi.setModifier(uid);
            xbi.setVersion(version + 1);
            //******* 更新账户表 ********
            flag = xnbiService.update(xbi, new EntityWrapper<Xnbi>().eq("uid", uid).eq("version", version));
            logger.debug(">>>xnbiService.update flag=" + flag);
        }
    }

    //积分及时入账
    private void addJifenFlow(User user, BigDecimal money, Boolean ruzhang, Integer fantimeType,
                              String sn, IotypeEnum iotype, JftypeEnum jftype, String remark) {
        Long uid = user.getId();
        Long mid = user.getMid();
        Long mpid = user.getMpid();

        JifenFlow jf = new JifenFlow();
        //*******  客户消耗  *******
        jf.setNum(money);
        jf.setSn(sn);//抵扣积分时 = 订单号
        jf.setIotype(iotype.getVal());//积分消费
        jf.setJftype(jftype.getVal());//积分消费
        jf.setFantimeType(fantimeType);
        jf.setCreatetime(new Date());
        jf.setUid(uid);
        jf.setMid(mid);
        jf.setMpid(mpid);
        jf.setRemark(remark);
        jf.setIsConfirm(1);
        jf.setConfirmDate(new Date());
        jf.setState(1);
        jf.insert();

        ruzhang = true;//积分及时入账,不在区分支付、核销、7天后入账

        Boolean flag = false;
        while (!flag) {
            Jifen jifen = jifenService.selectOne(new EntityWrapper<Jifen>().eq("uid", uid));
            if (jifen == null) jifen = initJifen(uid, mid, mpid);

            long v = jifen.getVersion();
            BigDecimal total = iotype.getVal() == 1 ? jifen.getTotal().add(jf.getNum()) : jifen.getTotal().subtract(jf.getNum());
            BigDecimal fanliing = iotype.getVal() == 1 ? jifen.getFanliing().add(jf.getNum()) : jifen.getFanliing().subtract(jf.getNum());

            if (ruzhang) jifen.setTotal(total);
            else jifen.setFanliing(fanliing);

            jifen.setVersion(jifen.getVersion() + 1);
            jifen.setModifytime(new Date());
            jifen.setModifier(uid);

            flag = jifenService.update(jifen, new EntityWrapper<Jifen>().eq("version", v).eq("uid", uid));
            logger.debug(">>>at jifenService update=" + flag);
        }
    }

    private void fanliRuzhang(String sn, String fantimeType) {
        Order order = orderService.selectOne(new EntityWrapper<Order>().eq("order_no", sn));

        if (order == null) {
            logger.info("--------------------------------------fanliRuzhang order not exist for sn=" + sn);
            return;
        }
        if (order.getFantimeType() == null) {
            logger.info("--------------------------------------fanliRuzhang order.getFantimeType is null for fantimeType=" + fantimeType);
            return;
        }
        logger.info("--------------------------------------fanliRuzhang order=" + order);
        if (!order.getFantimeType().toString().equals(fantimeType)) {
            logger.info("--------------------------------------fanliRuzhang fantimeType not equal sn=" + sn);
            return;
        }

        Long uid = order.getUid();
        Long mid = order.getMid();
        Long mpid = order.getMpid();

        AccountFlow af = accountFlowService.selectOne(new EntityWrapper<AccountFlow>()
                .eq("sn", sn)
                .eq("xftype", XftypeEnum.xffanli.getVal())
        );
        Boolean flag = false;
        if (af != null) {
            uid = af.getUid();
            MerchantConfig mconfig = redisService.getMconfig(order.getMpid());
            User user = userService.selectById(uid);
            MerchantApp mapp = redisService.getMApp(mpid);
            boolean fanxian = mconfig.getIsAutofan() == 1 && mconfig.getIsMiaotui() == 1;

            if (fanxian) {
                Map<String, Object> paymap = qnpay.payPakect(user.getMpid(), mapp.getAppid(), user, af.getRealpay(), "用户分享佣金奖励", "127.0.0.1");
                //如果秒退失败，该佣金自动到用户账户
                if (paymap.containsKey("result_code") && paymap.get("result_code").toString().equals("FAIL")) {
                    flag = false;
                } else if (paymap.containsKey("result_code") && paymap.get("result_code").toString().equals("SUCCESS")) {
                    //秒到账成功
                    addMaccountFlow(user, af.getAmount(), sn, IotypeEnum.output, XftypeEnum.xffanli);

                    AccountFlow naf = new AccountFlow();
                    naf.setAmount(af.getAmount());
                    naf.setDikou(new BigDecimal(0));//总营销金额 130
                    naf.setRealpay(new BigDecimal(0));//总价200 实付100

                    naf.setNickname(user != null ? user.getNickName() : null);
                    naf.setHeadimg(user != null ? user.getAvatarPic() : null);
                    naf.setPhone(user != null ? user.getPhone() : null);

                    naf.setSn(sn);
                    naf.setIotype(IotypeEnum.output.getVal());//个人账户出账
                    naf.setXftype(XftypeEnum.withdraw.getVal());//个人消费
                    naf.setFantimeType(af.getFantimeType());

                    naf.setIsConfirm(-1);
                    naf.setState(1);
                    naf.setTradetime(new Date());
                    naf.setCreatetime(af.getTradetime());
                    naf.setRemark("佣金提现至微信账户【" + sn + "】");
                    naf.setUid(uid);
                    naf.setMid(mid);
                    naf.setMpid(mpid);
                    naf.insert();

                    Account naccount = new Account();
                    while (!flag) {
                        Account account = accountService.selectOne(new EntityWrapper<Account>().eq("uid", uid));
                        if (account == null) {
                            account = initAccount(uid, mid, mpid);
                        }
                        af.setIsConfirm(1);
                        af.setLasttotal(account.getTotal());
                        af.setConfirmDate(new Date());

                        Long version = account.getVersion();

                        BigDecimal total = account.getTotal();
                        BigDecimal fanliing = account.getFanliing();

                        naccount.setTotal(total.subtract(af.getAmount()));
                        naccount.setFanliing(fanliing.subtract(af.getAmount()));

                        naccount.setModifytime(new Date());
                        naccount.setModifier(uid);
                        naccount.setVersion(version + 1);

                        flag = accountService.update(naccount, new EntityWrapper<Account>().eq("uid", uid).eq("version", version));
                        if (flag) naf.insertOrUpdate();
                    }
                }
            }
            //如果失败，直接转至余额账户
            Account naccount = new Account();
            while (!flag) {
                Account account = accountService.selectOne(new EntityWrapper<Account>().eq("uid", uid));
                if (account == null) {
                    break;
                }
                Long version = account.getVersion();

                BigDecimal amount = account.getAmount();
                BigDecimal fanliing = account.getFanliing();

                naccount.setAmount(amount.add(af.getAmount()));
                naccount.setFanliing(fanliing.subtract(af.getAmount()));

                naccount.setModifytime(new Date());
                naccount.setModifier(uid);
                naccount.setVersion(version + 1);

                flag = accountService.update(naccount, new EntityWrapper<Account>().eq("uid", uid).eq("version", version));
            }
        }

        JifenFlow jf = jifenFlowService.selectOne(new EntityWrapper<JifenFlow>()
                .eq("sn", sn)
                .eq("fantime_type", fantimeType)
                .eq("jftype", XftypeEnum.xffanli.getVal())
        );

        flag = false;
        while (!flag && jf != null) {
            uid = jf.getUid();

            Jifen jifen = jifenService.selectOne(new EntityWrapper<Jifen>().eq("uid", uid));
            if (jifen == null) {
                break;
            }
            Long version = jifen.getVersion();

            jifen.setTotal(jifen.getTotal().add(jf.getNum()));
            jifen.setFanliing(jifen.getFanliing().subtract(jf.getNum()));

            jifen.setModifytime(new Date());
            jifen.setModifier(uid);
            jifen.setVersion(version + 1);

            flag = jifenService.update(jifen, new EntityWrapper<Jifen>().eq("uid", uid).eq("version", version));
        }

        XnbiFlow xf = xnbiFlowService.selectOne(new EntityWrapper<XnbiFlow>()
                .eq("sn", sn)
                .eq("fantime_type", fantimeType)
                .eq("jftype", XftypeEnum.xffanli.getVal())
        );

        flag = false;
        while (!flag && xf != null) {
            uid = xf.getUid();

            Xnbi xbi = xnbiService.selectOne(new EntityWrapper<Xnbi>().eq("uid", uid));
            if (xbi == null) {
                break;
            }
            Long version = xbi.getVersion();

            xbi.setTotal(xbi.getTotal().add(xf.getNum()));
            xbi.setFanliing(xbi.getFanliing().subtract(xf.getNum()));

            xbi.setModifytime(new Date());
            xbi.setModifier(uid);
            xbi.setVersion(version + 1);

            flag = xnbiService.update(xbi, new EntityWrapper<Xnbi>().eq("uid", uid).eq("version", version));
        }
    }

    private void pintuanUpdate(Order order) {
        logger.info("---------------------orderActor pintuanUpdate coming at order=" + JSON.toJSONString(order));
        PintuanLog pintuanLog = pintuanLogService.selectOne(new EntityWrapper<PintuanLog>()
                .eq("oid", order.getId())
                .eq("uid", order.getUid()));
        if (pintuanLog == null) {
            logger.info("---------------------orderActor pintuanUpdate fail for pintuanLog null at order=" + JSON.toJSONString(order));
            return;
        }

        PintuanLog npintuanLog = new PintuanLog();
        npintuanLog.setId(pintuanLog.getId());
        npintuanLog.setState(1);
        npintuanLog.updateById();

        PintuanOpen pintuanOpen = pintuanOpenService.selectOne(new EntityWrapper<PintuanOpen>()
                .setSqlSelect("id,status,ptotal,pnumber")
                .eq("id", pintuanLog.getPtoid()));
        if (pintuanOpen == null) {
            logger.info("pintuanOpen not found for oid=" + order.getId());
            return;
        }
        pintuanOpen.setPnumber(pintuanOpen.getPnumber() + 1);
        if (pintuanOpen.getPtotal() - pintuanOpen.getPnumber() == 0) {
            pintuanOpen.setStatus(PTstatus.ok.getVal());

            List<PintuanLog> pintuanLogs = pintuanLogService.selectList(new EntityWrapper<PintuanLog>()
                    .eq("ptoid", pintuanOpen.getId()));
            //更新订单状态
            for (PintuanLog item : pintuanLogs) {
                Order norder = new Order();
                norder.setId(item.getOid());
                norder.setStatus(StatusEnum.receving.getVal());
                norder.updateById();
            }
        }

        pintuanOpen.setState(1);
        pintuanOpen.updateById();


    }

    private void kanjiaUpdate(Order order) {

        CutpriceOpen cutpriceOpen = cutpriceOpenService.selectOne(new EntityWrapper<CutpriceOpen>()
                .eq("oid", order.getId()));
        if (cutpriceOpen != null) {
            CutpriceOpen ncutpriceOpen = new CutpriceOpen();
            ncutpriceOpen.setId(cutpriceOpen.getId());
            ncutpriceOpen.setEndtime(new Date());
            ncutpriceOpen.setStatus(PTstatus.ok.getVal());
            ncutpriceOpen.setModifier(order.getUid());
            ncutpriceOpen.setModifytime(new Date());
            ncutpriceOpen.updateById();
        }
    }

    private void goodsAndOrderUpdate(Order order) {

        Goods goods = goodsService.selectById(order.getGid());
        logger.info("---------------------goodsAndOrderUpdate goods=" + JSON.toJSONString(goods));
        Goods ngoods = new Goods();
        ngoods.setId(order.getGid());
        ngoods.setCanyushu(goods.getCanyushu() == null ? 1 : goods.getCanyushu() + 1);

        ngoods.setNumberOrders(goods.getNumberOrders() + 1);
        ngoods.setNumberSale(goods.getNumberSale() + order.getGoodsNumber());

        if (goods.getStores() != null & goods.getStores().longValue() > 0
                && goods.getStores().intValue() <= ngoods.getNumberSale().intValue()) {
            ngoods.setStatus(Gstatus.over.getVal());
        }

        ngoods.setModifytime(new Date());
        ngoods.setModifier(order.getUid());
        logger.info("---------------------orderActor pintuanUpdate ngoods=" + JSON.toJSONString(ngoods));
        ngoods.updateById();

        //订单状态更新
        Order norder = new Order();
        norder.setId(order.getId());
        norder.setState(1);
        logger.info("--------------------------------------------------11----norder.getStatus()=" + norder.getStatus());
        if (order.getType().intValue() == YXType.pintuan.getVal()) norder.setStatus(StatusEnum.forsend.getVal());
        logger.info("--------------------------------------------------22----norder.getStatus()=" + norder.getStatus());
        norder.updateById();
    }

    private void tiyanka(Goods goods, Order order) {

        logger.info("---------------------------------------------------------------------------start to tiyanka");
        logger.info("---------------------------------------------------------------------------start to tiyanka");
        CouponTpl ctpl = couponTplService.selectById(goods.getTplid());
        logger.info("--------------------------------------couponTpl=" + JSON.toJSONString(ctpl));

        if (ctpl == null) return;

        Coupon coupon = new Coupon();
        coupon.setIsUnused(1);
        coupon.setIsUsed(0);
        coupon.setIsForever(0);
        coupon.setIsOutdate(0);
        coupon.setState(1);
        coupon.setUsemin(new BigDecimal(0));
        coupon.setPic(ctpl.getPic());
        coupon.setOid(order.getId());

        coupon.setMid(order.getMid());
        coupon.setMpid(order.getMpid());
        coupon.setUid(order.getUid());

        coupon.setCreatetime(new Date());

        coupon.setTplid(ctpl.getId());
        coupon.setType(ctpl.getType());
        coupon.setName(ctpl.getName());

        coupon.setCno(StringUtil.getQuanCode(order.getMid()));

        coupon.setStarttime(DateUtil.getToday());
        coupon.setEndtime(ctpl.getType().intValue() == 10 ? DateUtil.addToday(365) :
                ctpl.getType().intValue() == 11 ? DateUtil.addToday(7) :
                        ctpl.getType().intValue() == 12 ? DateUtil.addToday(30) :
                                ctpl.getType().intValue() == 13 ? DateUtil.addToday(90) :
                                        ctpl.getType().intValue() == 14 ? DateUtil.addToday(180) :
                                                ctpl.getType().intValue() == 15 ? DateUtil.addToday(365) :
                                                        ctpl.getType().intValue() == 16 ? DateUtil.addToday(3650) : "");

        coupon.setCost(ctpl.getCost());
        coupon.setUsemin(ctpl.getUsemin() == null ? new BigDecimal(0) : ctpl.getUsemin());
        coupon.setOriginType(4);//领券来源@1：领取；2：分享；3：赠送;4：充值&

        coupon.insert();

        //领取+1
        CouponTpl ctpl2 = new CouponTpl();
        ctpl2.setId(ctpl.getId());
        ctpl2.setUse(ctpl.getUse() + 1);
        ctpl2.setModifytime(new Date());
        ctpl2.setModifier(ctpl.getUid());
        ctpl2.updateById();
    }

}

